#!/usr/bin/perl
###############################################################################
# burn a sega cd from a backup
# requires all files for only one sega cd are in the PWD
#   * supports bin/cue
#   * supports iso/mp3
#   * supports iso/wav
###############################################################################

use strict;
use warnings;

###############################################################################
# configuration variables
###############################################################################

# useWav 0 (mp3) 1 (wav)

my $useWav = 1;

# useToc 0 (cue) 1 (toc)

my $useToc = 0;

my $deleteCreatedFiles = 0;
my $requireAudioFilesForIso = 0;

###############################################################################
# global variables
###############################################################################

# toc/cue file to use for burning

my $guide;

# list of large files generated by this script to delete when done

my @filesToDelete;

###############################################################################
# actual execution
###############################################################################

# check for bin/cue format

my @bins = (<*.bin>,<*.BIN>);
my @cues = (<*.cue>,<*.CUE>);

# determine format (bin/cue or iso/mp3 or iso/wav)

if ( $#bins == 0 && $#cues == 0 ) {

    # bin/cue format

    $guide = $cues[0];

} else {

    # look for iso/mp3 or iso/wav format

    # get iso name

    my @isos = (<*.iso>,<*.ISO>);

    if ( $#isos != 0 ) {
	die "Only support one iso in PWD";
    }

    my $iso = $isos[0];

    # convert mp3 files to wav files

    if ( $useWav ) {
	foreach my $mp3 ((<*.mp3>,<*.MP3>)) {
	    my $wav = $mp3;
	    $wav =~ s/\.mp3$/.wav/;
	    if ( ! -e $wav ) {
		system("mpg123 -w \"$wav\" \"$mp3\"");
		if ( $deleteCreatedFiles ) {
		    push @filesToDelete, $wav;
		}
	    }
	}
    }

    # collect audio (mp3/wave) file information

    my @audios;
    my $audioType;

    if ( $useWav ) {
	@audios = sort (<*.wav>,<*.WAV>);
	$audioType = 'WAVE';
    } else {
	@audios = sort (<*.mp3>,<*.MP3>);
	$audioType = 'MP3';
    }

    if ( $requireAudioFilesForIso && $#audios < 0 ) {
	die "No audio files found\n";
    }

    # determine toc and cue filenames

    $guide = $iso;
    if ( $useToc ) {
	$guide =~ s/\.iso$/.toc/;
	$guide =~ s/\.ISO$/.TOC/;
    } else {
	$guide =~ s/\.iso$/.cue/;
	$guide =~ s/\.ISO$/.CUE/;
    }

    # print toc/cue entry for data track

    my $guideText = '';

    if ( $useToc ) {
	$guideText .= "CD_ROM\n";
	$guideText .= "TRACK MODE1\n";
	$guideText .= "DATAFILE \"$iso\"\n";
    } else {
	$guideText .= "FILE \"$iso\" BINARY\n";
	$guideText .= "  TRACK 01 MODE1/2048\n";
	$guideText .= "    INDEX 01 00:00:00\n";
    }

    # print toc/cue entries for audio tracks
    # when track is 2, need to add a post-gap to track 1 and pre-gap to track 2

    my $track = 2;

    foreach my $audio (@audios) {
	if ( $useToc ) {
	    if ( $track == 2 ) {
		$guideText .= "ZERO 00:02:00 // post-gap\n";
		$guideText .= "\n";
	    }
	    $guideText .= "TRACK AUDIO\n";
	    if ( $track == 2 ) {
		$guideText .= "SILENCE 00:02:00 // pre-gap\n";
		$guideText .= "START\n";
	    }
	    $guideText .= "FILE \"$audio\" 0\n";
	    $guideText .= "\n";
	} else {
	    my $trackText = sprintf("%2.2d",$track);
	    if ( $track == 2 ) {
		$guideText .= "    POSTGAP 00:02:00\n";
	    }
	    $guideText .= "FILE \"$audio\" $audioType\n";
	    $guideText .= "  TRACK $trackText AUDIO\n";
	    if ( $track == 2 ) {
		$guideText .= "    PREGAP 00:02:00\n";
	    }
	    $guideText .= "    INDEX 01 00:00:00\n";
	}
	$track++;
    }

    # now write toc/cue file

    open( GUIDE, ">$guide" ) or die "Cannot write file: $guide\n";
    print GUIDE $guideText;
    close GUIDE;

    print $guideText;
}

# now burn the sega cd (guide already set to toc/cue accordingly to format)

# burn at 1x
system("cdrdao write --speed 1 --driver generic-mmc \"$guide\"");

# delete any generated files we made
# we keep the cue/toc since its a small file anyways

if ( $deleteCreatedFiles ) {
    foreach my $file (@filesToDelete) {
	system("rm \"$file\"");
    }
}
